package site.xying.dd;

import net.milkbowl.vault.economy.Economy;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.LinkedList;
import java.util.List;

/**
 * @author: Hisen
 * @date: 2019/2/1 13:06
 * @description:
 */
class EventListener implements Listener{
  private final DispatcherPlugin dispatcherPlugin;
  private final Economy economy;
  private final String X = "*";

  public EventListener(DispatcherPlugin dispatcherPlugin) {
    this.dispatcherPlugin = dispatcherPlugin;
    this.economy = dispatcherPlugin.getEconomy();
  }

  @EventHandler
  private void onEvent(PlayerDeathEvent event) {
    Player player = event.getEntity();

    ItemStack[] itemStacks = dropInventory(event, player);
    Integer dropMoney = dropMoney(player);
    Integer dropExp = dropExp(event, player);

    sendMessage(itemStacks, dropMoney, dropExp, player);

  }

  /**
   * 发送消息
   * @param itemStacks
   * @param dropMoney
   * @param dropExp
   * @param player
   */
  private void sendMessage(ItemStack[] itemStacks, Integer dropMoney, Integer dropExp, Player player) {
    if (itemStacks != null && itemStacks.length > 0) {
      StringBuilder stringBuilder = new StringBuilder(Config.frontDefaultColor).append("你掉落了物品：");
      for (ItemStack itemStack : itemStacks) {
        if (itemStack != null) {
          stringBuilder.append("[")
                  .append(Config.frontItemNameColor).append(itemStack.getType().name())
                  .append(Config.frontDefaultColor).append("] x ")
                  .append(Config.frontItemAmountColor).append(itemStack.getAmount())
                  .append(Config.frontDefaultColor).append(" ");
        }
      }
      player.sendMessage(stringBuilder.toString());
    }

    if (dropMoney != 0) {
      player.sendMessage(Config.frontDefaultColor + "你掉落了金钱： " + Config.frontMoneyColor + dropMoney);
    }

    if (dropExp != 0) {
      player.sendMessage(Config.frontDefaultColor + "你损失了 " + Config.frontExpColor + Config.dropExceptionPercentage + "%" + Config.frontDefaultColor +  " 的经验，共 " + Config.frontExpColor + dropExp + Config.frontDefaultColor +  " 级经验");
    }
  }

  private Integer dropExp(PlayerDeathEvent event, Player player) {
    if (!player.hasPermission(Const.Permission.DEATHDROP_EXP.getCmd()) && !player.isOp()) {
      int totalLevel = player.getLevel();
      if (totalLevel <= Config.dropExceptionMax) {
        return 0;
      }

      float dropExpPercentage = new Float(Config.dropExceptionPercentage) / 100;
      int droppedLevel = new Float(totalLevel * dropExpPercentage).intValue();
      if (droppedLevel <= 0){
        droppedLevel = -1;
      }else {
        droppedLevel = -droppedLevel;
      }

      player.giveExpLevels(droppedLevel);

      event.setDroppedExp(0);
      //Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "exp set " + player.getName() + " " + String.valueOf(totalExp - droppedExp));

      event.setKeepLevel(true);
      return -droppedLevel;
    }

    event.setKeepLevel(true);
    event.setDroppedExp(0);
    return 0;
  }

  private Integer dropMoney(Player player) {
    Integer dropMoneyAmount = 0;
    if (!player.hasPermission(Const.Permission.DEATHDROP_MONEY.getCmd()) && !player.isOp()) {
      if (economy == null) {
        return 0;
      }

      double playerMoney = economy.getBalance(player);
      dropMoneyAmount = Config.dropMoneyAmount;

      if (this.economy.has(player, dropMoneyAmount)) {
        this.economy.withdrawPlayer(player, dropMoneyAmount);
      }
    }
    return dropMoneyAmount;
  }

  private ItemStack[] dropInventory(PlayerDeathEvent event, Player player) {
    if (!player.hasPermission(Const.Permission.DEATHDROP_INVENTORY.getCmd()) && !player.isOp() && Config.dropItemMax != 0 && Config.dropItemAmount != 0) {
      Inventory playerInventory = player.getInventory();
      ItemStack[] itemStacks = playerInventory.getContents();
      List<Integer> hasItemLinkedList = new LinkedList<>();
      for (int i = 0; i < itemStacks.length; i++) {
        if (itemStacks[i] == null) {
          continue;
        }
        hasItemLinkedList.add(i);
      }
      if (hasItemLinkedList.size() == 0) {
        return null;
      }



      int dropSize = Config.dropItemAmount < Config.dropItemMax ? Config.dropItemAmount : Config.dropItemMax;
      dropSize = dropSize < hasItemLinkedList.size() ? dropSize : hasItemLinkedList.size();
      ItemStack[] dropStacks = new ItemStack[dropSize];
      Location location = player.getLocation();


      int count = 0;
      while (0 < hasItemLinkedList.size() && count < dropSize) {
        int index = (int) Math.round(Math.random() * (hasItemLinkedList.size() - 1));

        //如果未添加带指定lore
        if (hasLore(itemStacks[hasItemLinkedList.get(index)])) {
          hasItemLinkedList.remove(index);
          continue;
        }

        ItemStack itemStack = itemStacks[hasItemLinkedList.get(index)];
        int dropAmount = (int) Math.round(Math.random() * (Config.dropItemMax - 1));
        int amount = itemStack.getAmount();
        //设置掉落的数量
        itemStack.setAmount(amount < dropAmount ? amount : dropAmount);
        //生成掉落物品
        location.getWorld().dropItemNaturally(location, itemStack);
        //储存掉落的物品
        dropStacks[count++] = itemStack.clone();
        //设置背包物品
        itemStack.setAmount(amount < dropAmount ? 0 : amount - dropAmount);

        hasItemLinkedList.remove(index);
      }

      event.setKeepInventory(true);

      ItemStack[] dropResultStack = new ItemStack[count];
      for (int i = 0; i < count; i++) {
        dropResultStack[i] = dropStacks[i];
      }
      return dropResultStack;
    }
    event.setKeepInventory(true);
    return null;
  }


  private boolean hasLore(ItemStack itemStack){
    if (itemStack != null) {
      ItemMeta itemMeta = itemStack.getItemMeta();
      if (itemMeta.hasLore()) {
        List<String> itemLoreList = itemMeta.getLore();
        for (String lore : Config.loreList) {
          for (String item : itemLoreList) {
            //通配符处理
            String x = lore.substring(lore.length() - 1, lore.length());
            if (X.equals(x)) {
              String xBefore = lore.substring(0, lore.length() - 1);
              if (item.length() >= xBefore.length()) {
                if (item.substring(0, xBefore.length()).equals(xBefore)) {
                  return true;
                }
              }
              return false;
            }
            if (!"".equals(item) && lore.equals(item)) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }
}
